]> dgit.raspbian.org Git - gnome-shell.git/commitdiff
environment: Ignore animation events after shutdown
authorMarco Trevisan (Treviño) <mail@3v1n0.net>
Fri, 5 Dec 2025 22:14:29 +0000 (23:14 +0100)
committerFlorian Müllner <fmuellner@gnome.org>
Wed, 14 Jan 2026 18:06:46 +0000 (19:06 +0100)
As soon as the shutdown starts, any animation event does not make sense,
although during this phase the clutter timelines may still proceed and
potentially calling invalid code in their callbacks.

Prevent this from happening by disconnecting from any timeline signal
we are connected to as soon as the `shutdown` signal is emitted

Co-Authored-By: Florian Müllner <fmuellner@gnome.org>
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/3996>
(cherry picked from commit 240aa910dc842098c843cad498572660aee0c66f)

js/ui/environment.js

index 8cf764e95742442e7715f88991b91b5700e6b7b5..b971ed8aeaf3262caeadea9bde13c0b4644e5fa1 100644 (file)
@@ -18,6 +18,8 @@ import St from 'gi://St';
 import * as SignalTracker from '../misc/signalTracker.js';
 import {adjustAnimationTime} from '../misc/animationUtils.js';
 
+const sessionSignalHolder = new SignalTracker.TransientSignalHolder();
+
 setConsoleLogDomain('GNOME Shell');
 
 Gio._promisify(Gio.DataInputStream.prototype, 'fill_async');
@@ -153,14 +155,16 @@ function _easeActor(actor, params) {
     const [transition] = transitions;
 
     if (transition && transition.delay)
-        transition.connect('started', () => prepare());
+        transition.connectObject('started', () => prepare(), sessionSignalHolder);
     else
         prepare();
 
-    if (transition)
-        transition.connect('stopped', (t, finished) => callback(finished));
-    else
+    if (transition) {
+        transition.connectObject('stopped', (t, finished) => callback(finished),
+            sessionSignalHolder);
+    } else {
         callback(true);
+    }
 }
 
 function _easeAnimatableProperty(animatable, propName, target, params) {
@@ -244,11 +248,12 @@ function _easeAnimatableProperty(animatable, propName, target, params) {
     transition.set_to(target);
 
     if (transition.delay)
-        transition.connect('started', () => prepare());
+        transition.connectObject('started', () => prepare(), sessionSignalHolder);
     else
         prepare();
 
-    transition.connect('stopped', (t, finished) => callback(finished));
+    transition.connectObject('stopped',
+        (t, finished) => callback(finished), sessionSignalHolder);
 }
 
 // Add some bindings to the global JS namespace
@@ -276,6 +281,9 @@ GObject.Object.prototype.disconnect_object = function (...args) {
 
 SignalTracker.registerDestroyableType(Clutter.Actor);
 
+global.connectObject('shutdown', () => sessionSignalHolder.destroy(),
+    sessionSignalHolder);
+
 Cairo.Context.prototype.setSourceColor = function (color) {
     const {red, green, blue, alpha} = color;
     const rgb = [red, green, blue].map(v => v / 255.0);